/*
 * VHNavMainTree.java
 * Created on 9 août 2009
 *
 * VirtualHockey Internet Platform
 * http://code.google.com/p/virtualhockey/
 *
 * Copyright (c) 2005-2009, Jens and Jan Janke (VirtualHockey Project)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
 */

package com.hockeo.vhweb.client.ui.widget;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.data.BaseTreeLoader;
import com.extjs.gxt.ui.client.data.ModelIconProvider;
import com.extjs.gxt.ui.client.data.ModelStringProvider;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.data.TreeLoader;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.TreePanelEvent;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.util.IconHelper;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanelView;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel.TreeNode;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.hockeo.vhweb.client.VHMain;
import com.hockeo.vhweb.client.VHMainController;
import com.hockeo.vhweb.client.mvc.VHController;
import com.hockeo.vhweb.client.mvc.VHView;
import com.hockeo.vhweb.client.res.VHResConstants;
import com.hockeo.vhweb.client.ui.panels.VHTabPanelIntRankings;
import com.hockeo.vhweb.client.utils.VHJsData;
import com.hockeo.vhweb.client.utils.VHJsSimpleData;
import com.hockeo.vhweb.client.utils.VHJsSimpleData.ChildType;

/**
 * Main menu navigation tree.
 *
 * @version $Id$
 * @author jjanke
 */
public class VHNavMainTree extends LayoutContainer
{
  private static final String NODE_INT_STATS    = "intStats";
  private static final String NODE_INT_CONTESTS = "intContests";
  private static final String NODE_INT_RANKINGS = "intRankings";
  private VHView              d_view;
  private TreePanel<VHJsData> d_tree;

  /**
   * Creates a new country navigation tree.
   *
   * @param view the parent view
   */
  public VHNavMainTree( VHView view )
  {
    d_view = view;
  }

  @Override
  protected void onRender( Element parent, int index )
  {
    super.onRender( parent, index );
    setLayout( new FitLayout() );

    // data proxy
    //
    RpcProxy<List<VHJsData>> proxy = new RpcProxy<List<VHJsData>>() {
      @SuppressWarnings( "synthetic-access" )
      @Override
      protected void load( Object objParent, AsyncCallback<List<VHJsData>> callback )
      {
        VHJsData model = (VHJsData) objParent;

        if ( model == null )
          callback.onSuccess( getFirstLevelNodes() );
        else if ( model instanceof VHJsSimpleData )
          getSimpleDataChildNodes( callback, (VHJsSimpleData) model );
      }
    };

    // tree loader
    //
    TreeLoader<VHJsData> loader = new BaseTreeLoader<VHJsData>( proxy ) {
      @Override
      public boolean hasChildren( VHJsData data )
      {
        return ( data instanceof VHJsSimpleData && ( (VHJsSimpleData) data ).getChildType() != ChildType.NONE );
      }
    };

    // tree store
    //
    TreeStore<VHJsData> store = new TreeStore<VHJsData>( loader );

    // tree
    //
    d_tree = new TreePanel<VHJsData>( store );

    // tree view
    //
    d_tree.setView( new TreePanelView<VHJsData>() {
      /**
       * Overridden to avoid that the wait icon is not shown for nodes that are not loaded
       * from the server.
       */
      @SuppressWarnings( "unchecked" )
      @Override
      public void onLoading( TreeNode node )
      {
        VHJsData data = (VHJsData) node.getModel();

        if ( data.getId().equals( NODE_INT_STATS ) )
          return;

        super.onLoading( node );
      }
    } );

    // labels
    //
    d_tree.setLabelProvider( new ModelStringProvider<VHJsData>() {
      public String getStringValue( VHJsData model, String property )
      {
        if ( model instanceof VHJsSimpleData )
          return ( (VHJsSimpleData) model ).getLabel();
        else
          return model.getString( "id_translated" );

        // return "TODO";
      }
    } );

    // icons
    //
    d_tree.setIconProvider( new ModelIconProvider<VHJsData>() {
      public AbstractImagePrototype getIcon( VHJsData model )
      {
        if ( model instanceof VHJsSimpleData )
          return ( (VHJsSimpleData) model ).getIcon();
        else
          return IconHelper.create( "images/nav/" + model.getId() + "_16.png", 16, 16 );
      }
    } );

    // react to double-click events
    //
    d_tree.addListener( Events.OnDoubleClick, new Listener<TreePanelEvent<VHJsData>>() {
      @SuppressWarnings( "synthetic-access" )
      public void handleEvent( TreePanelEvent<VHJsData> evt )
      {
        VHJsData data = (VHJsData) evt.getNode().getModel();

        if ( data.getType().equals( "GChampionsLeague" ) || data.getType().equals( "GWorldLeague" ) )
          ( (VHMainController) d_view.getController() ).displayIntCup( data );
        else if ( data.getId().equals( NODE_INT_RANKINGS ) )
          ( (VHMainController) d_view.getController() ).displayPanel(
              new VHTabPanelIntRankings( d_view.getController() ), VHMain.getConstants().championsAndIntRankings(),
              VHMain.ICON_STANDINGS );
        else
          Window.alert( "Node '" + data.getId() + "' not (yet) handled." );
      }
    } );

    add( d_tree );
  }

  /**
   * Returns all the nodes forming the first level of the main menu tree.
   */
  private List<VHJsData> getFirstLevelNodes()
  {
    final List<VHJsData> list = new ArrayList<VHJsData>();
    final VHResConstants consts = VHMain.getConstants();
    VHJsSimpleData data;

    data = new VHJsSimpleData( NODE_INT_CONTESTS, consts.navMainInternationalContests(), VHMain.ICON_TROPHY );
    data.setChildType( VHJsSimpleData.ChildType.CLIENT );
    list.add( data );

    data = new VHJsSimpleData( NODE_INT_STATS, consts.navMainInternationalStats(), VHMain.ICON_STATS );
    data.setChildType( VHJsSimpleData.ChildType.CLIENT );
    list.add( data );

    return list;
  }

  /**
   * Creates child nodes of simple data nodes.
   */
  private void getSimpleDataChildNodes( AsyncCallback<List<VHJsData>> callback, VHJsSimpleData parent )
  {
    if ( parent.getId().equals( NODE_INT_CONTESTS ) )
      VHController.getBaseDataService().getInternationalContests( VHController.getLocale(), callback );
    else if ( parent.getId().equals( NODE_INT_STATS ) )
      createChildNodesForIntStats( callback, parent );
  }

  /**
   * Creates child nodes for the given parent node.
   *
   * @param callback the callback to which to add the child nodes
   * @param parent the parent node for which to create child nodes
   */
  private void createChildNodesForIntStats( AsyncCallback<List<VHJsData>> callback, VHJsSimpleData parent )
  {
    final List<VHJsData> list = new ArrayList<VHJsData>();
    final VHResConstants consts = VHMain.getConstants();
    VHJsSimpleData data;

    data = new VHJsSimpleData( NODE_INT_RANKINGS, consts.navMainIntRankings() + " (" + consts.navMainECRAbbrev() + ", "
        + consts.navMainENRAbbrev() + " etc.)", VHMain.ICON_STANDINGS );
    data.setChildType( VHJsSimpleData.ChildType.NONE );
    list.add( data );

    callback.onSuccess( list );
  }
}
